﻿// MainPage.xaml.cs (c) Copyright 2009, Mike Hodnick : www.hodnick.com
// Mouse wheel code adapted from:
// http://www.hanselman.com/blog/TheWeeklySourceCode18DeepZoomSeadragonSilverlight2MultiScaleImageMouseWheelZoomingAndPanningEdition.aspx


using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using Kindohm.KSynth.Library;
using System.Windows.Input;
using System.Windows.Shapes;
using System.Windows.Media;
using System;
using System.Diagnostics;
using System.Collections.ObjectModel;

namespace Kindohm.KSynth.AudioCanvas
{
    public partial class MainPage : UserControl
    {
        bool scrolling;
        CanvasManager manager;
        Point anchor;
        Point lastMousePos;
        double zoom = 1;
        Point lastCanvasMousePos;
        double MaxScroll = 2000;

        public MainPage()
        {
            InitializeComponent();
            this.HideInfo();
            this.DrawGrid();
            this.Loaded += new System.Windows.RoutedEventHandler(MainPage_Loaded);
        }

        void MainPage_Loaded(object sender, System.Windows.RoutedEventArgs e)
        {
            this.manager = new CanvasManager(this.mainCanvas);

            this.MouseLeftButtonDown += new MouseButtonEventHandler(MainPage_MouseLeftButtonDown);
            this.MouseLeftButtonUp += new MouseButtonEventHandler(MainPage_MouseLeftButtonUp);
            this.MouseMove += new MouseEventHandler(MainPage_MouseMove);

            ObservableCollection<Preset> presets = new ObservableCollection<Preset>(){
               new BassDronePreset(), new SomeOtherPreset()};
            this.presetList.ItemsSource = presets;

            new MouseWheelHelper(this).Moved += delegate(object wheelSender, MouseWheelEventArgs wheelArgs)
            {
                wheelArgs.Handled = true;
                if (wheelArgs.Delta > 0)
                    this.zoom = 1.2;
                else
                    this.zoom = .80;

                Zoom(zoom, this.lastMousePos);
            };

            Binding pulseEnabledBinding = new Binding();
            pulseEnabledBinding.Mode = BindingMode.TwoWay;
            pulseEnabledBinding.Source = manager.Pulsar;
            pulseEnabledBinding.Path = new PropertyPath("Enabled");
            this.pulseCheckBox.SetBinding(CheckBox.IsCheckedProperty, pulseEnabledBinding);
            this.pulseCheckBox.Checked += new RoutedEventHandler(pulseCheckBox_Checked);

            Binding tempoBinding = new Binding();
            tempoBinding.Mode = BindingMode.TwoWay;
            tempoBinding.Source = manager.Pulsar;
            tempoBinding.Path = new PropertyPath("Tempo");
            this.bmpSlider.SetBinding(Slider.ValueProperty, tempoBinding);

            StereoPcmStreamSource source = new StereoPcmStreamSource();
            source.Input = CanvasMixer.Volume;
            this.media.SetSource(source);
        }


        void DrawGrid()
        {
            double spacing = 50;
            double count = 200;
            double start = -2000;

            for (int i = 0; i < count; i++)
            {
                Line line = new Line();
                line.Stroke = new SolidColorBrush(Color.FromArgb(255, 33, 33, 33));
                line.X1 = start + spacing * i;
                line.X2 = line.X1;
                line.Y1 = start;
                line.Y2 = start + spacing * count;

                this.mainCanvas.Children.Add(line);

                line = new Line();
                line.Stroke = new SolidColorBrush(Color.FromArgb(255, 33, 33, 33));
                line.X1 = start;
                line.X2 = start + spacing * count;
                line.Y1 = start + spacing * i;
                line.Y2 = line.Y1;

                this.mainCanvas.Children.Add(line);

            }

        }

        void Zoom(double zoom, Point pointToZoom)
        {
            if ((zoom < 1 & this.scale.ScaleX > .7) | (zoom > 1 & this.scale.ScaleX < 2))
            {
                this.scale.ScaleX = this.scale.ScaleX * zoom;
                this.scale.ScaleY = this.scale.ScaleY * zoom;
                this.scale.CenterX = this.lastCanvasMousePos.X;
                this.scale.CenterY = this.lastCanvasMousePos.Y;
            }
        }


        void MainPage_MouseMove(object sender, MouseEventArgs e)
        {
            this.lastMousePos = e.GetPosition(this);
            this.lastCanvasMousePos = e.GetPosition(this.mainCanvas);
            if (this.scrolling)
            {
                double xDiff = lastMousePos.X - anchor.X;
                double yDiff = lastMousePos.Y - anchor.Y;

                this.manager.Scrolling = true;
                this.scroll.X += (xDiff);
                this.scroll.Y += (yDiff);

                Debug.WriteLine("ScrollX: " + this.scroll.X.ToString("0000") + ", ScrollY: " + this.scroll.Y.ToString("0000"));

                // -2800 and zero


                if (this.scroll.X > -2000)
                    this.scroll.X = -2000;
                else if (this.scroll.X < -4800)
                    this.scroll.X = -4800;

                if (this.scroll.Y > -2000)
                    this.scroll.Y = -2000;
                else if (this.scroll.Y < -4800)
                    this.scroll.Y = -4800;

                this.anchor = lastMousePos;
            }
        }

        void MainPage_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            this.scrolling = false;
            this.manager.Scrolling = false;
        }

        void MainPage_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (this.manager.Scrollable)
            {
                this.anchor = e.GetPosition(this);
                this.scrolling = true;
            }
        }



        void pulseCheckBox_Checked(object sender, RoutedEventArgs e)
        {
            if (Prompts.ShowPulse)
            {
                this.infoBox.Visibility = Visibility.Visible;
                this.line.Visibility = Visibility.Visible;
            }
        }

        private void muteCheckBox_Checked(object sender, RoutedEventArgs e)
        {
            this.media.Stop();
        }

        private void muteCheckBox_Unchecked(object sender, RoutedEventArgs e)
        {
            this.media.Play();
        }

        private void HyperlinkButton_Click(object sender, RoutedEventArgs e)
        {
            this.HideInfo();
            Prompts.ShowPulse = false;
        }

        void HideInfo()
        {
            this.infoBox.Visibility = Visibility.Collapsed;
            this.line.Visibility = Visibility.Collapsed;
        }

        private void presetList_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (presetList.SelectedItem != null)
            {
                Prompts.ShowPulse = false;
                Preset preset = presetList.SelectedItem as Preset;
                this.pulseCheckBox.IsChecked = preset.PulseEnabled;
                this.bmpSlider.Value = preset.PulseBpm;
                this.manager.LoadPreset(preset);
            }
        }

    }
}
